home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / -archivi / -recent2 / amhelios.lha / AmHelios / p_clip4.cpp < prev    next >
C/C++ Source or Header  |  1997-07-13  |  5KB  |  200 lines

  1. ////////////////////////////////////////////////////////////
  2. //
  3. //  P_CLIP4.CPP - 4-D Polygon Clipper Class
  4. //
  5. //  Version:    1.03A
  6. //
  7. //  History:    94/08/23 - Version 1.00A release.
  8. //              94/12/16 - Version 1.01A release.
  9. //              95/02/05 - Version 1.02A release.
  10. //              95/07/21 - Version 1.02B release.
  11. //              96/02/14 - Version 1.02C release.
  12. //              96/04/01 - Version 1.03A release.
  13. //
  14. //  Compilers:  Microsoft Visual C/C++ Professional V1.5
  15. //              Borland C++ Version 4.5
  16. //
  17. //  Author:     Ian Ashdown, P.Eng.
  18. //              byHeart Software Limited
  19. //              620 Ballantree Road
  20. //              West Vancouver, B.C.
  21. //              Canada V7S 1W3
  22. //              Tel. (604) 922-6148
  23. //              Fax. (604) 987-7621
  24. //
  25. //  Copyright 1994-1996 byHeart Software Limited
  26. //
  27. //  The following source code has been derived from:
  28. //
  29. //    Ashdown, I. 1994. Radiosity: A Programmer's
  30. //    Perspective. New York, NY: John Wiley & Sons.
  31. //
  32. //  It may be freely copied, redistributed, and/or modified
  33. //  for personal use ONLY, as long as the copyright notice
  34. //  is included with all source code files.
  35. //
  36. ////////////////////////////////////////////////////////////
  37.  
  38. #include "p_clip4.h"
  39.  
  40. PolyClip4::PolyClip4()  // PolyClip4 class constructor
  41. {
  42.   Vector4 temp;     // Temporary vector
  43.  
  44.   // Link edge-plane clippers
  45.   pclip = &(clipper[Front]);
  46.   clipper[Front].Add(&(clipper[Back]));
  47.   clipper[Back].Add(&(clipper[Left]));
  48.   clipper[Left].Add(&(clipper[Right]));
  49.   clipper[Right].Add(&(clipper[Top]));
  50.   clipper[Top].Add(&(clipper[Bottom]));
  51.   clipper[Bottom].Add(NULL);
  52.  
  53.   // Set clipper plane normals
  54.  
  55.   temp = Vector4(0.0, 0.0, 1.0, 0.0);
  56.   clipper[Front].SetNormal(temp.Norm());
  57.  
  58.   temp = Vector4(0.0, 0.0, -1.0, 1.0);
  59.   clipper[Back].SetNormal(temp.Norm());
  60.  
  61.   temp = Vector4(1.0, 0.0, 0.0, 0.0);
  62.   clipper[Left].SetNormal(temp.Norm());
  63.  
  64.   temp = Vector4(-1.0, 0.0, 0.0, 1.0);
  65.   clipper[Right].SetNormal(temp.Norm());
  66.  
  67.   temp = Vector4(0.0, -1.0, 0.0, 1.0);
  68.   clipper[Top].SetNormal(temp.Norm());
  69.  
  70.   temp = Vector4(0.0, 1.0, 0.0, 0.0);
  71.   clipper[Bottom].SetNormal(temp.Norm());
  72. }
  73.  
  74. // Clip polygon
  75. int PolyClip4::Clip( Element3 *pelem, OutPolygon &out,
  76.     double (*ptm)[4] )
  77. {
  78.   int i;            // Loop index
  79.   int num_vert;     // Number of vertices
  80.   Vertex3 *pvert;   // 3-D world space vertex pointer
  81.   Vertex4 hv;       // 4-D homogeneous co-ord vertex
  82.  
  83.   out.Reset();  // Reset output polygon
  84.  
  85.   num_vert = pelem->GetNumVert();
  86.   for (i = 0; i < num_vert; i++)
  87.   {
  88.     // Get world space vertex position pointer
  89.     pvert = pelem->GetVertexPtr(i);
  90.  
  91.     // Set homogeneous co-ordinates vertex
  92.     hv.Set(pvert->GetPosn(), pvert->GetExitance(), ptm);
  93.  
  94.     pclip->Clip(hv, out);       // Clip polygon edge
  95.   }
  96.  
  97.   pclip->Close(out);    // Close polygon
  98.       
  99.   return out.GetNumVert();
  100. }
  101.  
  102. // Output view space vertex
  103. void ClipEdge::Output( Vertex4 &v, OutPolygon &out )
  104. {
  105.   if (pnext != NULL)    // More planes ?
  106.     pnext->Clip(v, out);
  107.   else
  108.     out.AddVertex(v);
  109. }
  110.  
  111. // Calculate intersection vertex
  112. Vertex4 ClipEdge::Intersect( Vertex4 &s, Vertex4 &e )
  113. {
  114.   double d, t;      // Temporary variables
  115.   Spectra color;    // Temporary color
  116.   Vector4 p, r;     // Temporary vectors
  117.   Vertex4 v;        // Temporary vertex
  118.  
  119.   // Calculate parameter
  120.   r = (e.GetCoord() - s.GetCoord());
  121.   d = Dot(normal, r);
  122.  
  123.   if (fabs(d) > MIN_VALUE)
  124.     t = -Dot(normal, s.GetCoord()) / d;
  125.   else
  126.     t = 1.0;
  127.  
  128.   if (t < 0.0)  // Ensure lower limit
  129.     t = 0.0;
  130.  
  131.   if (t > 1.0)  // Ensure upper limit
  132.     t = 1.0;
  133.  
  134.   // Calculate intersection vertex co-ordinates
  135.   r *= t;
  136.   p = s.GetCoord() + r;
  137.       
  138.   // Linearly interpolate vertex color
  139.   color = Blend(s.GetColor(), e.GetColor(), t);
  140.  
  141.   v.Set(p, color);
  142.  
  143.   return v;
  144. }
  145.  
  146. // Clip polygon edge
  147. void ClipEdge::Clip( Vertex4 ¤t, OutPolygon &out )
  148. {
  149.   BOOL curr_inside;     // Current point inside flag
  150.   Vertex4 isect;        // Intersection vertex
  151.  
  152.   // Determine vertex visibility
  153.   curr_inside = IsInside(current);
  154.  
  155.   if (first_flag == FALSE)      // First vertex seen ?
  156.   {
  157.     first = current;
  158.     first_inside = curr_inside;
  159.     first_flag = TRUE;
  160.   }
  161.   else
  162.   {
  163.     // Does edge intersect plane ?
  164.     if (start_inside ^ curr_inside)
  165.     {
  166.       isect = Intersect(start, current);
  167.       Output(isect, out);
  168.     }
  169.   }
  170.  
  171.   if (curr_inside == TRUE)
  172.     Output(current, out);
  173.  
  174.   start = current;
  175.   start_inside = curr_inside;
  176. }
  177.  
  178. // Close polygon
  179. void ClipEdge::Close( OutPolygon &out )
  180. {
  181.   Vertex4 isect;        // Intersection vertex
  182.  
  183.   if (first_flag == TRUE)
  184.   {
  185.     // Does edge intersect plane ?
  186.     if (start_inside ^ first_inside)
  187.     {
  188.       isect = Intersect(start, first);
  189.       Output(isect, out);
  190.     }
  191.  
  192.     if (pnext != NULL)  // More planes ?
  193.       pnext->Close(out);
  194.  
  195.     // Reset first vertex seen flag
  196.     first_flag = FALSE;
  197.   }
  198. }
  199.  
  200.